home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
C/C++ Users Group Library 1996 July
/
C-C++ Users Group Library July 1996.iso
/
vol_100
/
172_01
/
ytab.c
< prev
next >
Wrap
Text File
|
1980-01-01
|
26KB
|
948 lines
/*
HEADER: CUG nnn.nn;
TITLE: LEX - A Lexical Analyser Generator
VERSION: 1.1 for IBM-PC
DATE: Jan 30, 1985
DESCRIPTION: A Lexical Analyser Generator. From UNIX
KEYWORDS: Lexical Analyser Generator YACC C PREP
SYSTEM: IBM-PC and Compatiables
FILENAME: YTAB.C
WARNINGS: This program is not for the casual user. It will
be useful primarily to expert developers.
CRC: N/A
SEE-ALSO: YACC and PREP
AUTHORS: Charles H. Forsyth
Scott Guthery 11100 leafwood lane Austin, TX 78750
Andrew M. Ward, Jr. Houston, Texas (Modifications)
COMPILERS: LATTICE C
REFERENCES: UNIX Systems Manuals -- Lex Manual on distribution disks
*/
/*
* Copyright (c) 1978 Charles H. Forsyth
*
* Modified 02-Dec-80 Bob Denny -- Conditionalize debug code for reduced size
* Modified 29-May-81 Bob Denny -- Clean up overlay stuff for RSX.
* More 19-Mar-82 Bob Denny -- New C library & compiler
* More 03-May-82 Bob Denny -- Final touches, remove unreferenced autos
* More 29-Aug-82 Bob Denny -- Clean up -d printouts
* More 29-Aug-82 Bob Denny -- Reformat for readability and comment
* while learning about LEX.
* More 20-Nov-83 Scott Guthery -- Adapt for IBM PC & DeSmet C
*
* Modified 22-Jun-86 Andrew Ward -- Modified code to compile under Lattice C
* version 3.0h. Corrected several errors
* from the assumption that pointers and
* integers are the same size.
* New debug code for LATTICE C using assert
* to test for wild pointers.
*/
#include <stdio.h>
#include <assert.h>
#include <stdlib.h>
#include <string.h>
#include "lexlex.h"
char ccl[ (NCHARS+1) / NBPC ];
int sz_ccl = (NCHARS+1) / NBPC;
char *yysterm[] = {
"error",
"NAME",
"CCLASS",
"STRING",
"CONCAT",
0 };
extern char *progname;
extern char *breakc;
extern char *ignore;
extern char *illeg;
extern int nlook;
char *lalloc();
struct des {
struct nfa *d_start;
struct nfa *d_final;
};
struct nlist {
struct nlist *nl_next;
struct nfa *nl_base;
struct nfa *nl_end;
struct nfa *nl_start;
struct nfa *nl_final;
char *nl_name;
}
*nlist;
extern int str_len;
extern struct nfa *nfap;
extern struct nfa *elem(int, char *);
extern struct des *newdp(struct nfa *, struct nfa *);
extern struct nlist *lookup(char *);
extern int mapc(int);
extern int cclass(void);
extern void name(int);
extern void action(void);
extern void skipstr(int);
extern void copycode(void);
extern void string(int);
extern void copynfa(struct nlist *, struct nfa *, struct des *);
extern void spccl(char *, char *, struct des *, char **);
extern void unget( int );
extern void copy(char *, char *, int);
extern void errmsg(char *);
extern void yyerror(char *, char *);
extern void newcase(int);
extern void llactr(void);
extern void setline(void);
extern void cclprint(char *);
extern int yyline;
typedef union {
char *buff;
struct nlist *list;
struct des *des_ptr;
struct nfa *elem_ptr;
} YYSTYPE;
#define NAME 257
#define CCLASS 258
#define STRING 259
#define CONCAT 260
#define yyclearin yychar = -1
#define yyerrok yyerrflag = 0
extern int yychar;
extern short yyerrflag;
#ifndef YYMAXDEPTH
#define YYMAXDEPTH 150
#endif
YYSTYPE yylval, yyval;
struct nfa *np, *nbase;
char *cp;
struct des *dp, *dp1;
struct trans *tp;
struct nlist *nl;
int i, c;
#define YYERRCODE 256
/*
* Lexical analyser
* (it isn't done with lex...)
*/
char buffer[150];
int yylex()
{
int c;
/* char *cp; */
int lno;
if (yyline == 0)
yyline++;
loop:
c = get();
if (isupper(c)) {
name(c);
yylval.buff = strlwr( yylval.buff );
return(STRING);
}
else if (islower(c) || c == '_') {
name(c);
return(NAME);
}
switch (c) {
case EOF:
return(0);
case '[':
return(cclass());
case '(':
case ')':
case '{':
case '}':
case '*':
case '|':
case '=':
case ';':
case '%':
return(c);
case '/':
if ((c = get()) != '*') {
unget(c);
return('/');
}
lno = yyline;
for (; c != EOF; c = get())
if (c == '*')
if ((c = get()) == '/')
goto loop;
else
unget(c);
yyline = lno;
errmsg("End of file in comment");
case '\'':
case '"':
yylval.buff = buffer;
string(c);
return(STRING);
case '\n':
case '\r':
case ' ':
case '\t':
goto loop;
default:
yylval.buff = buffer;
/* if (c == '\\') {
unget(c);
c = mapch(EOF);
}
*/
buffer[0] = c;
buffer[1] = '\0';
str_len = 1;
return(STRING);
}
/* ERR: Warning 85: function return value mismatch */
}
int cclass()
{
int c, i, lc;
int compl;
compl = 0;
/* Zero the ccl array */
for (i = 0; i < sz_ccl; i++) ccl[i] = '\0';
/* Check if exclusion definition */
if ((c = get()) == '^') compl++;
else unget(c);
lc = -1;
while( ( c = mapc(']') ) != EOF)
{
if (c == '-' && lc >= 0)
{
if((c = mapc(']')) == EOF) break;
/* Map 'c' into bit pattern */
for(i = lc; i <= c; i++) ccl[ i / NBPC ] |= 1 << (i % NBPC);
lc = -1;
continue;
}
ccl[ c / NBPC ] |= 1 << ( c % NBPC );
lc = c;
}
if (compl) {
for (i = 0; i < sz_ccl; i++)
ccl[i] ^= -1;
if (aflag == 0)
for (i = 0200; i < ( 1 << NBPC ); i++)
ccl[i/NBPC] &= ~(1 << (i%NBPC));
}
yylval.buff = newccl( ccl );
return(CCLASS);
}
void string(ec)
int ec;
{
char *cp;
int c;
extern int str_len;
for(cp = buffer; (c = mapc(ec)) != EOF;)
*cp++ = c;
*cp = '\0';
str_len = strlen( buffer );
}
int mapc(ec)
int ec;
{
int c, v, i;
if((c = get()) == ec) return(EOF);
switch(c) {
case EOF:
errmsg("End of file in string");
return(c);
case '\\':
if ((c = get()) >= '0' && c <= '7') {
i = 0;
for (v = 0; c>='0' && c<='7' && i++<3; c = get())
v = v*010 + c-'0';
unget(c);
return(v&CMASK);
}
switch (c) {
case 'n':
return('\n');
case 't':
return('\t');
case 'b':
return('\b');
case 'r':
return('\r');
case '\n':
yyline++;
return(mapc(ec));
}
default:
}
return(c);
}
void name(c)
int c;
{
char *cp;